package base.thread_demo.demo08_09;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.locks.LockSupport;

/**
 *  通过该案例可以:
 *  1.更清晰的认识 Thread..isInterrupted() 和 Thread.interrupted() 的区别
 *  2.LockSupport.park();对于线程打断标识为false的,才会阻塞线程继续执行(park住),
 *  如果检测到打断标识为true,则不再阻塞线程继续执行(理解成都打断了,还park干啥)
 *
 *
 */
public class ParkAndInterrupt {
    private static final Logger log = LoggerFactory.getLogger(ParkAndInterrupt.class);

    public static void main(String[] args) throws InterruptedException {
//        park1();
        park2();
    }


    /**
     * Thread..interrupt() 打断被 LockSupport.park()阻塞的线程
     */
    public static void park1 () throws InterruptedException {
        Thread t1 = new Thread(()->{
            for (int i = 0; i < 2; i++) {
                log.info("park{}....", i);
                LockSupport.park();
                log.info("unpark{}....", i);
                // isInterrupted()方法只检测线程是否被打断过，因此当二次循环时LockSupport.park()不会阻塞线程,程序结束.
                log.info("t1线程打断标识状态:{}", Thread.currentThread().isInterrupted());
            }
        },"t1");
        t1.start();

        Thread.sleep(2000);
        t1.interrupt();// 去打断被 park 住的 t1 线程
    }

    /**
     * LockSupport.park()准备阻塞线程前,先检测线程打断标识是否为false,是的话就park住.
     */
    public static void park2() throws InterruptedException {
        Thread t2 = new Thread(()->{
            for (int i = 0; i < 2; i++) {
                log.info("park{}....", i);
                LockSupport.park();
                log.info("unpark{}....", i);
                // interrupted()方法返回线程打断与否的检测结果,并最后设置线程打断标识为false.
                // 因此当二次循环时LockSupport.park(),检测到线程打断标识为false,就会再次park()阻塞线程,程序僵死.
                log.info("t1线程打断标识状态:{}", Thread.interrupted());
                //.info("t1线程打断标识状态:{}", Thread.interrupted());//false
            }
        },"t2");
        t2.start();

        Thread.sleep(2000);
        t2.interrupt();
    }
}
